﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TCommon
{
    public partial class MessageBoardForm : Form
    {
        private Font font = new Font("微软雅黑", 14);
        private Font userFont = new Font("微软雅黑", 12);
        private SolidBrush brush = new SolidBrush(Color.Black);
        private SolidBrush msgbrush = new SolidBrush(Color.FromArgb(255, 205, 39, 39));
        private SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(255, 204, 204, 204));
        private System.Drawing.Pen p = new System.Drawing.Pen(Color.FromArgb(255, 204, 204, 204), 0);
        private System.Timers.Timer msgTimer = new System.Timers.Timer();
        private List<FloatMessage> messageList = new List<FloatMessage>();
        private int lineCount = 0;
        private int lineHeight = 35;

        public MessageBoardForm(Point location, int width, int height)
        {
            SetStyle(ControlStyles.UserPaint |
                   ControlStyles.AllPaintingInWmPaint |
                   ControlStyles.OptimizedDoubleBuffer |
                   ControlStyles.ResizeRedraw |
                   ControlStyles.SupportsTransparentBackColor, true);
            this.TopMost = true;
            this.FormBorderStyle = FormBorderStyle.None;
            this.BackColor = Color.White;
            this.TransparencyKey = Color.White;
            InitializeComponent();
            this.Closed += OnClosed;
            msgTimer.Interval = 50;
            msgTimer.Elapsed += MsgTimer_Elapsed;
            msgTimer.Start();

            //System.Timers.Timer timer = new System.Timers.Timer();
            //timer.Interval = 2000;
            //timer.Elapsed += Timer_Elapsed;
            //timer.Start();

            this.Show();
            UpdateLS(location, width, height);
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new Action(() => {
                ShowMsg("吴沈杰：大家好，我是吴沈杰!", this.Location, this.Width, this.Height);
            }));           
        }

        private void MsgTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new Action(() => {
                foreach (var msg in messageList)
                {
                    msg.X = msg.X - 5;
                }

                var messageNeedRemove = new ConcurrentBag<FloatMessage>();
                foreach (var msg in messageList)
                {
                    if (msg.X < -(msg.Width + msg.Width1 + 8))
                    {
                        messageNeedRemove.Add(msg);
                    }
                }

                foreach (var msgd in messageNeedRemove)
                {
                    messageList.Remove(msgd);
                }

                this.Refresh();               
            }));
        }

        public void ShowMsg(string msg, Point location, int width, int height)
        {
            var floatMessage = new FloatMessage();
            floatMessage.Message = msg;
            floatMessage.X = this.Width;
            floatMessage.Y = lineCount * lineHeight;
            messageList.Add(floatMessage);
            if (lineCount < 8)
            {
                lineCount++;
            }
            else
            {
                lineCount = 0;
            }         
        }

        public void UpdateLS(Point location, int width, int height, bool visible = true) {
            var x = location.X + 10;
            var y = location.Y + 50;
            this.Location = new Point(x, y);
            this.Width = width - 20;
            this.Height = height - 100;
        }

        private void OnClosed(object sender, EventArgs e)
        {
            msgTimer.Close();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            foreach (var message in messageList)
            {
                Graphics g = e.Graphics;
                if (message.Width == 0)
                {
                    var array = message.Message.Split('：');
                    var userString = array[0] + "：";
                    message.userString = userString;
                    var messageString = array[1];
                    if (messageString.Length > 30)
                    {
                        message.msgString = messageString.Substring(0, 29) + "...";
                    }
                    else
                    {
                        message.msgString = messageString;
                    }
                    SizeF vSizeF = g.MeasureString(userString, userFont);
                    message.Width = (int)Math.Ceiling(vSizeF.Width) + 2;
                    message.Height = (int)Math.Ceiling(vSizeF.Height);
                    SizeF msgSizeF = g.MeasureString(message.msgString, font);
                    message.Width1 = (int)Math.Ceiling(msgSizeF.Width) + 4;
                    message.Height1 = (int)Math.Ceiling(msgSizeF.Height);
                }
                var point = new PointF(message.X, message.Y + 3);

                drawRoundedRect(g, p, message.X - 6, message.Y-2, message.Width + message.Width1-6, message.Height1+4, 5);

                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                g.DrawString(message.userString, userFont, brush, point);
                var msgPoint = new PointF(message.X - 15 + message.Width, message.Y);
                g.DrawString(message.msgString, font, msgbrush, msgPoint);
            }
        }

        private void drawRoundedRect(Graphics g, System.Drawing.Pen pen, int x, int y, int width, int height, int radius)
        {
            //去掉圆角的锯齿
            //g.SmoothingMode = SmoothingMode.HighQuality;

            Rectangle rect = new Rectangle(new Point(x, y), new Size(width, height));
            GraphicsPath Rect = new GraphicsPath();
            // 添加圆弧
            Rect.AddArc(x, y, radius * 2, radius * 2, 180, 90);
            Rect.AddArc(x+rect.Width - radius * 2 - 1, y, radius * 2, radius * 2, 270, 90);
            Rect.AddArc(x+rect.Width - radius * 2 - 1, y+rect.Height - radius * 2 - 1, radius * 2, radius * 2, 0, 90);
            Rect.AddArc(x, y+rect.Height - radius * 2 - 1, radius * 2, radius * 2, 90, 90);
            Rect.CloseFigure();
            g.DrawPath(pen, Rect);
            g.FillPath(semiTransBrush, Rect);
        }

        private class FloatMessage {
            public string Message { get; set; }

            public string userString { get; set; }

            public string msgString { get; set; }

            public int Line { get; set; }

            public int X { get; set; }

            public int Y { get; set; }

            public int Width { get; set; }

            public int Height { get; set; }

            public int Width1 { get; set; }

            public int Height1 { get; set; }
        }
    }
}
